The Look@NanoSIMS (short LANS) Matlab module written by Lubos Polerecky (Polerecky L., Adam B., Milucka J., Musat N., Vagner T. and Kuypers M. M. M. (2012) Look@NanoSIMS - a tool for the analysis of nanoSIMS data in environmental microbiology. Environ. Microbiol. 14, 1009–1023.) makes it easy to process NanoSIMS data and draw regions of interest (ROI). The lans2r package provides a convenient interface to import the ROI data generated by LANS into R for those interested in processing and plotting the data in R. This R markdown example demonstrates the basic functionality of the lans2r package. Please also consult the package help, e.g. ?load_LANS_summary.

Installation

You can install this package directly from GitHub using the devtools package.

install.packages("devtools")
devtools::install_github('sebkopf/lans2r')

Load data

To load data into R, export it from LANS which creates a folder for each analysis with sub folders dat containing the aggregated information about the different ROIs (in text file format) and mat containing the raw ion maps (in Matlab file format). Both of these can be imported easily with this package. For easier demonstration lans2r bundles a set of 3 analyses (folders analysis1, analysis2 and analysis3) with the package sources.

library(lans2r)
folder <- system.file("extdata", "nanosims_data", package = "lans2r") # data base directory

ROI overview data

This loads the ROI overview data for the 3 analyses and assigns some additional information to the analyses (here rather random, column info). Since the parameters quiet=F indicates that information messages should be provided, it also outputs a summary of the loaded data.

data <- 
  load_LANS_summary (
    analysis = c("analysis1", "analysis2", "analysis3"), # the analysis folders
    base_dir = folder, # the data base director
    load_zstacks = T, # whether to load z-stacks as well (have to be exported from LANS!)
    info = c("turtle", "jetpack", "pizza"), # any additional information about the analyses
    quiet = F # output information about the files
  ) 
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis1/dat' read successfully.
##       Data for 37 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis2/dat' read successfully.
##       Data for 33 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis3/dat' read successfully.
##       Data for 34 ROIs with 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       Z-stacks were loaded. Recovered 2 planes.

To calculate ratios and abundances, simply specificy which ions you would like to ratio. Note: for convenience, we make use of the pipe operator %>% for chaining multiple operations. For more information on the pipe, take a look at the magrittr package.

data <- data %>% 
  calculate_sums(c("13C", "12C"), c("15N12C", "14N12C")) %>% 
  calculate_ratios(c("13C", "12C"), c("15N12C", "14N12C"), c("13C+12C", "15N12C+14N12C")) %>% # calculate ratios
  calculate_abundances(c("13C", "12C"), c("15N12C", "14N12C")) # calculate abundances
## INFO: 624 'ion_sum' values + errors calculated and added to the data frame
##       values added (stored in 'variable' column): '13C+12C' (312x), '15N12C+14N12C' (312x)
## INFO: 936 'ratio' values + errors calculated and added to the data frame
##       values added (stored in 'variable' column): '13C/12C' (312x), '13C+12C/15N12C+14N12C' (312x), '15N12C/14N12C' (312x)
## INFO: 624 'abundance' values + errors calculated and added to the data frame
##       values added (stored in 'variable' column): '13C F' (312x), '15N12C F' (312x)

For additional operations, one can use the more generic calculate function and provide custom functions for value and error calculations and name construction. Here, we have APE (atom percent enrichment) as an example.

data <- data %>% 
  mutate(F13C_natural = 1.111, F15N_natural = 0.366) %>% 
  calculate(
    data_type = "APE",
    c("13C F", "F13C_natural", "13C F sigma"), 
    c("15N12C F", "F15N_natural", "15N12C F sigma"),
    # calculate the APE value as the fractional abundance enrichment above natural
    value_fun = function(val, nat, sigma) val - nat,
    # assume the error in natural abundance is negligible so only F error propagates
    error_fun = function(val, nat, sigma) sigma,
    # replace the F in the existing columnes with APE to make the new variable
    name_fun = function(val_col, ...) sub("F", "APE", val_col)
  )
## INFO: 624 'APE' values + errors calculated and added to the data frame
##       values added (stored in 'variable' column): '13C APE' (312x), '15N12C APE' (312x)

Overview

Let’s take a look at the first couple of rows of the data frame.

library(knitr)
data %>% head(n=10) %>% kable()
analysis info plane ROI data_type variable value sigma coord_x coord_y size pixels LW_ratio F13C_natural F15N_natural
analysis1 turtle all 1 ion_count 12C 1895850 1376.89869 17.38 192.93 0.83 353 2.45 1.111 0.366
analysis1 turtle all 2 ion_count 12C 1273919 1128.68020 18.39 175.25 0.75 290 1.57 1.111 0.366
analysis1 turtle all 3 ion_count 12C 1315417 1146.91630 40.38 168.26 0.70 250 1.66 1.111 0.366
analysis1 turtle all 4 ion_count 12C 1289955 1135.76186 42.05 207.80 0.72 267 2.16 1.111 0.366
analysis1 turtle all 5 ion_count 12C 1756159 1325.20149 42.92 147.66 0.81 334 2.50 1.111 0.366
analysis1 turtle all 6 ion_count 12C 1023934 1011.89624 46.56 103.93 0.67 232 2.11 1.111 0.366
analysis1 turtle all 7 ion_count 12C 5509 74.22264 52.29 22.77 1.32 893 1.09 1.111 0.366
analysis1 turtle all 8 ion_count 12C 1117870 1057.29372 61.77 120.06 0.62 195 2.39 1.111 0.366
analysis1 turtle all 9 ion_count 12C 1122839 1059.64098 63.38 146.02 0.65 217 2.02 1.111 0.366
analysis1 turtle all 10 ion_count 12C 1046665 1023.06647 74.39 98.29 0.66 221 2.23 1.111 0.366

Since this is now in long format so it’s easy to have both value and the sigma error, it’s hard to see line by line what is going on, let’s look just at analysis1 and recast the values into a wide format (using package tidyr but the older version reshape2 could achieve the same).

library(tidyr)
data %>% 
  filter(plane == "all", analysis == "analysis1") %>% 
  select(-data_type, -sigma) %>% 
  spread(variable, value) %>% 
  kable()
analysis info plane ROI coord_x coord_y size pixels LW_ratio F13C_natural F15N_natural 12C 13C 13C APE 13C F 13C/12C 13C+12C 13C+12C/15N12C+14N12C 14N12C 15N12C 15N12C APE 15N12C F 15N12C/14N12C 15N12C+14N12C
analysis1 turtle all 1 17.38 192.93 0.83 353 2.45 1.111 0.366 1895850 24315 0.1552974 1.2662974 0.0128254 1920165 0.2413707 7839685 115568 1.0867256 1.452726 0.0147414 7955253
analysis1 turtle all 2 18.39 175.25 0.75 290 1.57 1.111 0.366 1273919 16087 0.1360485 1.2470485 0.0126280 1290006 0.2259213 5625982 83997 1.1050562 1.471056 0.0149302 5709979
analysis1 turtle all 3 40.38 168.26 0.70 250 1.66 1.111 0.366 1315417 17084 0.1711004 1.2821004 0.0129875 1332501 0.2262195 5802914 87388 1.1175912 1.483591 0.0150593 5890302
analysis1 turtle all 4 42.05 207.80 0.72 267 2.16 1.111 0.366 1289955 16221 0.1308694 1.2418694 0.0125749 1306176 0.2229323 5773380 85690 1.0965188 1.462519 0.0148423 5859070
analysis1 turtle all 5 42.92 147.66 0.81 334 2.50 1.111 0.366 1756159 22267 0.1410622 1.2520622 0.0126794 1778426 0.2427387 7218762 107741 1.1045652 1.470565 0.0149251 7326503
analysis1 turtle all 6 46.56 103.93 0.67 232 2.11 1.111 0.366 1023934 13166 0.1585015 1.2695015 0.0128583 1037100 0.2303558 4434979 67186 1.1263043 1.492304 0.0151491 4502165
analysis1 turtle all 7 52.29 22.77 1.32 893 1.09 1.111 0.366 5509 75 0.2321232 1.3431232 0.0136141 5584 0.1079555 51019 706 0.9989106 1.364911 0.0138380 51725
analysis1 turtle all 8 61.77 120.06 0.62 195 2.39 1.111 0.366 1117870 13971 0.1233607 1.2343607 0.0124979 1131841 0.2294823 4858391 73758 1.1294536 1.495454 0.0151816 4932149
analysis1 turtle all 9 63.38 146.02 0.65 217 2.02 1.111 0.366 1122839 14201 0.1379446 1.2489446 0.0126474 1137040 0.2325619 4818643 70550 1.0769784 1.442978 0.0146411 4889193
analysis1 turtle all 10 74.39 98.29 0.66 221 2.23 1.111 0.366 1046665 13408 0.1538186 1.2648186 0.0128102 1060073 0.2328937 4484536 67210 1.1105762 1.476576 0.0149871 4551746
analysis1 turtle all 11 75.33 194.09 0.70 251 2.50 1.111 0.366 1474738 19091 0.1669910 1.2779910 0.0129454 1493829 0.2517476 5846622 87214 1.1037744 1.469774 0.0149170 5933836
analysis1 turtle all 12 81.03 80.98 0.66 224 2.10 1.111 0.366 1248264 15887 0.1457328 1.2567328 0.0127273 1264151 0.2631618 4733143 70559 1.1028463 1.468846 0.0149074 4803702
analysis1 turtle all 13 88.09 54.91 0.84 358 2.29 1.111 0.366 1800117 22854 0.1426678 1.2536678 0.0126958 1822971 0.2357692 7617556 114458 1.1143129 1.480313 0.0150256 7732014
analysis1 turtle all 14 92.22 120.89 0.47 115 1.63 1.111 0.366 568527 7220 0.1430230 1.2540230 0.0126995 575747 0.2333178 2431404 36247 1.1028868 1.468887 0.0149078 2467651
analysis1 turtle all 15 103.21 191.31 0.71 261 2.45 1.111 0.366 1316299 16719 0.1432216 1.2542216 0.0127015 1333018 0.2453287 5354216 79383 1.0949654 1.460965 0.0148263 5433599
analysis1 turtle all 16 103.61 87.10 0.65 220 1.93 1.111 0.366 938611 11923 0.1433476 1.2543476 0.0127028 950534 0.2014485 4648242 70254 1.1229066 1.488907 0.0151141 4718496
analysis1 turtle all 17 121.74 210.82 0.74 282 3.85 1.111 0.366 1362635 17326 0.1445427 1.2555427 0.0127151 1379961 0.2404504 5654394 84673 1.1093792 1.475379 0.0149747 5739067
analysis1 turtle all 18 124.16 187.82 0.75 290 1.79 1.111 0.366 1400489 17601 0.1301765 1.2411765 0.0125678 1418090 0.2443121 5719442 84978 1.0980222 1.464022 0.0148577 5804420
analysis1 turtle all 19 125.39 24.63 0.99 503 2.68 1.111 0.366 2361751 29706 0.1311716 1.2421716 0.0125780 2391457 0.2286148 10307418 153222 1.0987479 1.464748 0.0148652 10460640
analysis1 turtle all 20 127.43 164.74 0.79 320 2.17 1.111 0.366 1368881 17212 0.1307637 1.2417637 0.0125738 1386093 0.2243803 6086953 90474 1.0985904 1.464590 0.0148636 6177427
analysis1 turtle all 21 136.29 113.77 1.32 893 1.09 1.111 0.366 8054 87 -0.0423352 1.0686648 0.0108021 8141 0.1296358 62003 796 0.9015361 1.267536 0.0128381 62799
analysis1 turtle all 22 140.19 223.32 0.85 370 3.50 1.111 0.366 1827876 23319 0.1486728 1.2596728 0.0127574 1851195 0.2247337 8116426 120857 1.1011949 1.467195 0.0148904 8237283
analysis1 turtle all 23 146.01 71.39 0.83 350 3.51 1.111 0.366 1679413 21240 0.1379320 1.2489320 0.0126473 1700653 0.2422029 6919252 102354 1.0917007 1.457701 0.0147926 7021606
analysis1 turtle all 24 164.97 228.62 0.73 274 1.76 1.111 0.366 1516371 19472 0.1568379 1.2678379 0.0128412 1535843 0.2506847 6036085 90507 1.1112813 1.477281 0.0149943 6126592
analysis1 turtle all 25 169.68 28.04 0.59 181 2.44 1.111 0.366 891849 11450 0.1565759 1.2675759 0.0128385 903299 0.2200872 4044012 60265 1.1023463 1.468346 0.0149023 4104277
analysis1 turtle all 26 181.15 92.59 0.81 336 2.23 1.111 0.366 1638021 20747 0.1397475 1.2507475 0.0126659 1658768 0.2456711 6654647 97339 1.0756351 1.441635 0.0146272 6751986
analysis1 turtle all 27 183.90 67.12 0.91 424 4.13 1.111 0.366 2112810 26716 0.1376878 1.2486878 0.0126448 2139526 0.2465096 8551138 128144 1.1104355 1.476436 0.0149856 8679282
analysis1 turtle all 28 183.29 172.77 1.32 893 1.09 1.111 0.366 5741 60 -0.0766956 1.0343044 0.0104511 5801 0.1133916 50541 618 0.8419986 1.207999 0.0122277 51159
analysis1 turtle all 29 184.37 29.74 0.60 186 2.53 1.111 0.366 1020716 12973 0.1440196 1.2550196 0.0127097 1033689 0.2221571 4584436 68528 1.1067817 1.472782 0.0149480 4652964
analysis1 turtle all 30 190.63 16.30 0.72 266 2.68 1.111 0.366 1334489 16868 0.1372268 1.2482268 0.0126400 1351357 0.2213835 6013066 91080 1.1261006 1.492101 0.0151470 6104146
analysis1 turtle all 31 196.02 117.40 0.84 365 3.47 1.111 0.366 1786621 22397 0.1270750 1.2380750 0.0125360 1809018 0.2216513 8040776 120772 1.1137683 1.479768 0.0150199 8161548
analysis1 turtle all 32 205.67 54.95 0.62 196 1.74 1.111 0.366 791714 9750 0.1055238 1.2165238 0.0123151 801464 0.2180309 3622960 52959 1.0747010 1.440701 0.0146176 3675919
analysis1 turtle all 33 219.40 141.15 0.94 457 2.81 1.111 0.366 1862303 23685 0.1448404 1.2558404 0.0127181 1885988 0.2069385 8984273 129486 1.0547749 1.420775 0.0144125 9113759
analysis1 turtle all 34 225.73 68.66 0.73 273 2.32 1.111 0.366 1259561 15944 0.1390147 1.2500147 0.0126584 1275505 0.2390906 5258553 76265 1.0635708 1.429571 0.0145030 5334818
analysis1 turtle all 35 230.29 107.77 1.32 893 1.09 1.111 0.366 9820 125 0.1459130 1.2569130 0.0127291 9945 0.1146371 85665 1087 0.8869970 1.252997 0.0126890 86752
analysis1 turtle all 36 238.29 25.77 1.32 893 1.09 1.111 0.366 9279 89 -0.1609573 0.9500427 0.0095916 9368 0.1036581 89258 1116 0.8688684 1.234868 0.0125031 90374
analysis1 turtle all 37 246.95 68.93 0.61 188 1.76 1.111 0.366 899748 11237 0.1225000 1.2335000 0.0124891 910985 0.2210931 4060267 60101 1.0926319 1.458632 0.0148022 4120368

Plotting

Plot all the data using the ggplot package.

library(ggplot2)
data %>% 
  ggplot() +
  aes(size, value, color = paste(analysis, info), shape = plane) + 
  geom_errorbar(aes(ymin = value - 2*sigma, ymax = value + 2*sigma), colour="black", width = 0) +
  geom_point(size=3) + 
    labs(x = expression("ROI size ["*mu*"m"^2*"]"), y="", 
         title = expression("ROI summary (2"*sigma*" error bars, may be smaller than symbols)"),
         color = "Analysis") + 
  facet_wrap(~variable, scales="free", nrow = 2) + 
  theme_bw()

Focus in on the combined counts (not the individual planes from the z-stack) and look just at ratios:

last_plot() %+% (data %>% filter(plane == "all", data_type == "ratio"))

Ion maps

Again, loading the ion maps for all 3 analyses.

maps <- 
  load_LANS_maps (
    analysis = c("analysis1", "analysis2", "analysis3"),
    base_dir = folder
  ) 
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis1/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       37 ROIs identified in the frame.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis2/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       33 ROIs identified in the frame.
## INFO: folder '/Library/Frameworks/R.framework/Versions/3.2/Resources/library/lans2r/extdata/nanosims_data/analysis3/mat' read successfully.
##       Ion map data for 256 x 256 pixel frame (10.014 microm^2) for 4 ions recovered: 12C, 13C, 14N12C, 15N12C.
##       34 ROIs identified in the frame.

The data in these looks similar to the summary data frame except that it is broken out pixel by pixel:

maps %>% head(n=10) %>% kable()
analysis x.px y.px frame_size.px x.um y.um frame_size.um variable data_type value sigma ROI
analysis1 1 1 256 0.0391172 0.0391172 10.014 12C ion_count 1721 41.48494 0
analysis1 1 2 256 0.0391172 0.0782344 10.014 12C ion_count 1694 41.15823 0
analysis1 1 3 256 0.0391172 0.1173516 10.014 12C ion_count 1508 38.83298 0
analysis1 1 4 256 0.0391172 0.1564688 10.014 12C ion_count 1297 36.01389 0
analysis1 1 5 256 0.0391172 0.1955859 10.014 12C ion_count 1136 33.70460 0
analysis1 1 6 256 0.0391172 0.2347031 10.014 12C ion_count 786 28.03569 0
analysis1 1 7 256 0.0391172 0.2738203 10.014 12C ion_count 702 26.49528 0
analysis1 1 8 256 0.0391172 0.3129375 10.014 12C ion_count 453 21.28380 0
analysis1 1 9 256 0.0391172 0.3520547 10.014 12C ion_count 319 17.86057 0
analysis1 1 10 256 0.0391172 0.3911719 10.014 12C ion_count 220 14.83240 0

To make it easier to plot these kind of maps, lans2r provides a convenience functoin plot_maps but of course this could be adjusted as needed (look at the source code to see how this one is made). By default ion counts are normalized for each ion so they can be visualized on the same scale.

plot_maps(maps)

Focusing in on just one ion, we can ditch the normalization, and let’s also not draw ROIs for a direct look. Also, because it’s a ggplot, all ggplot modifications of the plot are fair game.

plot_maps(maps %>% filter(variable == "14N12C", analysis %in% c("analysis1", "analysis2")), 
          normalize = FALSE, draw_ROIs = FALSE) + 
  theme(legend.position = "right") + labs(fill = "ion count")

Future directions

Note that for plotting maps, lans2r does not (yet) support any smoothing so although the plot_maps function theoretically supports plotting ratios and abundances as well (which can be calculated from the maps data the same way using calculate_ratios and calculate_abundances), in practice this does not work so well because individual pixels often have extreme values offsetting proper scaling. This might be part of future expansions if the package sees a lot of use so please email with suggestions if you find it helpful.